package com.atguigu.netty.mqtt;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.mqtt.MqttDecoder;
import io.netty.handler.codec.mqtt.MqttEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class NettyMqttClient {

    private static Logger logger = LoggerFactory.getLogger(Thread.currentThread().getClass());

    private String host = "36.133.152.73";
    private int port = 1883;

    /**
     * 重连策略
     */
    private RetryPolicy retryPolicy;

    NioEventLoopGroup eventLoopGroup;

    private Bootstrap bootstrap;

    public NettyMqttClient() {
        this.retryPolicy = new ExponentialBackOffRetry(1000, Integer.MAX_VALUE, 60 * 1000);
    }

    public void init() throws InterruptedException {
        // 客户端需要一个时间循环组
        eventLoopGroup = new NioEventLoopGroup();
        // 创建客户端启动对象
        // 客户端使用Bootstrap
        bootstrap = new Bootstrap();

        // 设置参数
        bootstrap.group(eventLoopGroup) // 设置线程组
                .channel(NioSocketChannel.class) // 设置客户端通道实现类（反射）
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new ReconnectHandler(NettyMqttClient.this));
                        ch.pipeline().addLast(MqttEncoder.INSTANCE);
                        ch.pipeline().addLast(new MqttDecoder());
                        ch.pipeline().addLast(new NettyMqttClientHandler());
                    }
                });

        logger.info("客户端 ok。。。。。");

        // 启动客户端连接服务端
        // ChannelFuture设置netty的异常模型
        // 直到连接返回，才会继续后面的执行，否则阻塞当前线程
        ChannelFuture channelFuture = bootstrap.connect(host, port);


    }

    public RetryPolicy getRetryPolicy() {
        return this.retryPolicy;
    }

    public void connect() {
        bootstrap.connect(host, port);
    }

    public void close() {
        eventLoopGroup.shutdownGracefully();
    }

    public static void main(String[] args) throws InterruptedException {
        new NettyMqttClient().init();
    }


}
